package mk.jug.academy.service;

import java.util.List;

import mk.jug.academy.model.Page;
import mk.jug.academy.model.Student;
import mk.jug.academy.model.status.StudentStatus;


/**
 * A contract depicting the services available regarding the functionality
 * tied to the {@link Student} model entity.
 * 
 * @author Ice.Penov
 */
public interface StudentService {

	/**
	 * Registers a student by persisting it to the DB
	 * with the {@link StudentStatus#SIGNED_UP}
	 */
	void registerStudent(Student student);

	/**
	 * Fetch all available students in the system,
	 * in a paged manner.
	 */
	Page<Student> listAll(int pageNumber, int itemsPerPage);
	
	/**
	 * Fetches currently signed up students to the academy (in the {@link StudentStatus#SIGNED_UP} status),
	 * in a paged manner. 
	 */
	Page<Student> listSignedUp(int pageNumber, int itemsPerPage);
	
	/**
	 * Fetches students in the {@link StudentStatus#WAITING_FOR_ENROLLMENT} status,
	 * in a paged manner.
	 */
	Page<Student> listWaitingForEnrollment(int pageNumber, int itemsPerPage);
	
	/**
	 * Returns the list containing all the {@link StudentStatus#WAITING_FOR_ENROLLMENT} students.
	 */
	List<Student> fetchWaiting();
	
	/**
	 * Fetches students in the {@link StudentStatus#ENROLLED} status,
	 * in a paged manner.
	 */
	Page<Student> listEnrolled(int pageNumber, int itemsPerPage);
	
	/**
	 * Fetches students in the {@link StudentStatus#REJECTED} status,
	 * in a paged manner.
	 */
	Page<Student> listRejected(int pageNumber, int itemsPerPage);
	
	/**
	 * An admin approves the registration. After this the
	 * student lands in the {@link StudentStatus#WAITING_FOR_ENROLLMENT} state.
	 */
	void approveRegistration(Student student);

	/**
	 * An admin denies the registration. The student lands in the {@link StudentStatus#REJECTED} state.
	 */
	void denyRegistration(Student student);
	
	/**
	 * Loads a {@link Student} given its ID.
	 */
	Student load(Long id);
	
	/**
	 * Saves the changes.
	 */
	void saveChanges(Student student);
	
	/**
	 * Checks whether this email is already registered with a {@link Student}.
	 */
	boolean exists(String email);

	/**
	 * Gets the {@link Student} by email.
	 */
	Student findByEmail(String email);
}